from datetime import datetime

from flask_sqlalchemy import SQLAlchemy

from tools import generate_id, underline_to_camel

db = SQLAlchemy()


class BaseModel(db.Model):
    """
    普通模型基类
    """

    __abstract__ = True
    id = db.Column(
        db.BigInteger, primary_key=True, comment="主键", default=generate_id()
    )
    createTime = db.Column(
        db.DateTime, name="create_time", default=datetime.now, comment="创建时间"
    )
    updateTime = db.Column(
        db.DateTime,
        name="update_time",
        default=datetime.now,
        onupdate=datetime.now,
        comment="更新时间",
    )
    createUser = db.Column(db.BigInteger, name="create_user", comment="创建用户")
    updateUser = db.Column(db.BigInteger, name="update_user", comment="更新用户")
    isDeleted = db.Column(
        db.Boolean, name="is_deleted", default=False, comment="逻辑删除:0=未删除,1=删除"
    )

    def __init__(self, **kwargs):
        """
        构造函数，将dict=>obj
        :param kwargs: 校验表单的**form.data
        """
        for key, value in kwargs.items():
            if hasattr(self, key):
                self.__dict__.update({key: value})

    def to_dict(self, row_handler=None):
        """
        对象转成dict
        :return:
        """
        m_dict = {}
        if self is not None:
            for c in self.__table__.columns:
                key = underline_to_camel(c.name)
                if hasattr(self, key):
                    value = getattr(self, key)
                    if value is not None:
                        if str(c.type) == "BIGINT":
                            m_dict[key] = str(value)
                        else:
                            m_dict[key] = value

        if row_handler is not None:
            m_dict = row_handler(m_dict)

        return m_dict

    @staticmethod
    def to_page(page, row_handler=None):
        # print(page.page) # 当前页码-从1开始
        # print(page.per_page) # 每页大小
        # print(page.total)    # 总记录数
        # print(page.items)    # 数据集
        if page is None:
            return None
        rows = []
        for u in page.items:
            rows.append(u.to_dict(row_handler))
        return {
            "recordCount": page.total,
            "totalPage": int((page.total - 1) / page.per_page) + 1,
            "pageSize": page.per_page,
            "pageNum": page.page,
            "rows": rows,
        }

    @staticmethod
    def to_dict_list(datas, row_handler=None):
        if datas is None:
            return []
        rows = []
        for u in datas:
            rows.append(u.to_dict(row_handler))
        return rows

    def remove(self, model, ids):
        """
        批量删除
        :param ids: 主键ID数组
        :return:
        """
        if ids is None or len(ids) == 0:
            return
        if getattr(model, "isDeleted") is None:
            # 直接删除
            db.session.query(model).filter(model.id.in_(ids)).delete()
        else:
            # 逻辑删除
            db.session.query(model).filter(model.id.in_(ids)).update(
                {"isDeleted": True}
            )


class TreeModel(BaseModel):
    """
    树型表模型基类
    """

    __abstract__ = True
    parentId = db.Column(
        db.BigInteger, name="parent_id", primary_key=True, default=0, comment="父ID"
    )
    name = db.Column(db.String(64), name="name", nullable=False, comment="名称")
    sort = db.Column(
        db.BigInteger, name="sort", default=99, nullable=False, comment="排序"
    )
